import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Random;

public class Tank {

	private int x;
	private int y;
	private int oldX;
	private int oldY;
	private boolean good;
	private int life = 100;
	private boolean live = true;
	private boolean bR = false, bU = false, bL = false, bD = false;

	public static final int WIDTH = 30;
	public static final int HEIGHT = 30;

	public static final int XSPEED = 5;
	public static final int YSPEED = 5;

	private TankClient tc;
	Direction dir = Direction.STOP;
	Direction ptDir = Direction.D;
	Random r = new Random();
	private BloodBar bb = new BloodBar();

	private int step = r.nextInt(12) + 3;
	
	public Tank(boolean good,TankClient tc){
		x = r.nextInt(700) + 30;
		y = r.nextInt(90);
		this.good = good;
		this.tc = tc;
	}

	public Tank(int x, int y, TankClient tc) {
		this.x = x;
		this.y = y;
		this.tc = tc;
	}

	public Tank(int x, int y, boolean good, TankClient tc) {
		this(x, y, tc);
		this.good = good;
		oldX = x;
		oldY = y;
	}

	public boolean isLive() {
		return live;
	}

	public void setLive(boolean live) {
		this.live = live;
	}

	public boolean isGood() {
		return good;
	}

	public void setGood(boolean good) {
		this.good = good;
	}

	public int getLife() {
		return life;
	}

	public void setLife(int life) {
		this.life = life;
	}

	public void draw(Graphics g) {
		// TODO Auto-generated method stub
		if (!live) {
			tc.tanks.remove(this);
			return;
		}
		if (this.good && this.live)
			bb.draw(g);
		Color c = g.getColor();
		if (good)
			g.setColor(Color.RED);
		else
			g.setColor(Color.BLUE);
		g.fillOval(x, y, 30, 30);
		g.setColor(Color.BLACK);
		switch (ptDir) {
		case L:
			g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y
					+ Tank.HEIGHT / 2);
			break;
		case LU:
			g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y);
			break;
		case U:
			g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH
					/ 2, y);
			break;
		case RU:
			g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH,
					y);
			break;
		case R:
			g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH,
					y + Tank.HEIGHT / 2);
			break;
		case RD:
			g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH,
					y + Tank.HEIGHT);
			break;
		case D:
			g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH
					/ 2, y + Tank.HEIGHT);
			break;
		case LD:
			g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y
					+ Tank.HEIGHT);
			break;
		}

		move();
	}

	private void move() {
		// TODO Auto-generated method stub
		oldX = x;
		oldY = y;
		switch (dir) {
		case R:
			x += XSPEED;
			break;
		case RU:
			x += XSPEED;
			y -= YSPEED;
			break;
		case U:
			y -= YSPEED;
			break;
		case LU:
			x -= XSPEED;
			y -= YSPEED;
			break;
		case L:
			x -= XSPEED;
			break;
		case LD:
			x -= XSPEED;
			y += YSPEED;
			break;
		case D:
			y += YSPEED;
			break;
		case RD:
			x += XSPEED;
			y += YSPEED;
			break;
		case STOP:
			break;

		}

		if (this.dir != Direction.STOP) {
			this.ptDir = this.dir;
		}

		if (!good) {
			Direction[] dirs = Direction.values();
			if (0 == step) {
				step = r.nextInt(12) + 3;
				int rn = r.nextInt(dirs.length);
				this.dir = dirs[rn];
			}
			step--;
			if (r.nextInt(50) > 48)
				this.fire();
		}

		if (x <= 0)
			x = 0;
		if (x >= TankClient.GAME_WIDTH - Tank.WIDTH)
			x = TankClient.GAME_WIDTH - Tank.WIDTH;
		if (y <= 30)
			y = 30;
		if (y >= TankClient.GAME_HEIGHT - Tank.HEIGHT)
			y = TankClient.GAME_HEIGHT - Tank.HEIGHT;
	}

	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		int key = e.getKeyCode();
		switch (key) {
		case KeyEvent.VK_RIGHT:
			bR = true;
			break;
		case KeyEvent.VK_UP:
			bU = true;
			break;
		case KeyEvent.VK_LEFT:
			bL = true;
			break;
		case KeyEvent.VK_DOWN:
			bD = true;
			break;
		case KeyEvent.VK_F2:
			this.live = true;
			this.life = 100;
			break;
		}
		locateDirection();

	}

	private void locateDirection() {
		// TODO Auto-generated method stub
		if (bR && !bU && !bL && !bD)
			dir = Direction.R;
		if (bR && bU && !bL && !bD)
			dir = Direction.RU;
		if (!bR && bU && !bL && !bD)
			dir = Direction.U;
		if (!bR && bU && bL && !bD)
			dir = Direction.LU;
		if (!bR && !bU && bL && !bD)
			dir = Direction.L;
		if (!bR && !bU && bL && bD)
			dir = Direction.LD;
		if (!bR && !bU && !bL && bD)
			dir = Direction.D;
		if (bR && !bU && !bL && bD)
			dir = Direction.RD;
		if (!bR && !bU && !bL && !bD)
			dir = Direction.STOP;
	}

	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		int key = e.getKeyCode();
		switch (key) {
		case KeyEvent.VK_CONTROL:
			fire();
			break;
		case KeyEvent.VK_RIGHT:
			bR = false;
			break;
		case KeyEvent.VK_UP:
			bU = false;
			break;
		case KeyEvent.VK_LEFT:
			bL = false;
			break;
		case KeyEvent.VK_DOWN:
			bD = false;
			break;
		case KeyEvent.VK_A:
			superfire();
		}
		locateDirection();
	}

	private void fire() {
		// TODO Auto-generated method stub
		if (!live)
			return;
		int x = this.x + Tank.WIDTH / 2 - Missile.WIDTH / 2;
		int y = this.y + Tank.WIDTH / 2 - Missile.WIDTH / 2;
		Missile m = new Missile(x, y, ptDir, good, tc);
		tc.missiles.add(m);
	}

	private void fire(Direction dir) {
		// TODO Auto-generated method stub
		if (!live)
			return;
		int x = this.x + Tank.WIDTH / 2 - Missile.WIDTH / 2;
		int y = this.y + Tank.WIDTH / 2 - Missile.WIDTH / 2;
		Missile m = new Missile(x, y, dir, good, tc);
		tc.missiles.add(m);
	}

	public Rectangle getRect() {
		return new Rectangle(x, y, Tank.WIDTH, Tank.HEIGHT);
	}

	public void hitTank(Tank tank) {
		if (this != tank) {
			if (this.isLive() && this.getRect().intersects(tank.getRect())
					&& tank.isLive()) {
				this.stay();
				tank.stay();
			}
		}
	}

	private void stay() {
		// TODO Auto-generated method stub
		x = oldX;
		y = oldY;
	}

	public void hitTanks(List<Tank> tanks) {
		// TODO Auto-generated method stub
		for (int i = 0; i < tanks.size(); i++) {
			Tank tank = tanks.get(i);
			this.hitTank(tank);
		}
	}

	public void hitWall(Wall wall) {
		if (this.isLive() && this.getRect().intersects(wall.getRect())) {
			this.stay();
		}
	}

	public void superfire() {
		Direction[] dirs = Direction.values();
		for (int i = 0; i < 8; i++) {
			dir = dirs[i];
			fire(dir);
		}

	}

	public void hitBoold(Blood blood) {
		if (this.live && this.getRect().intersects(blood.getRect())
				&& blood.isLive()) {
			blood.setLive(false);
			this.setLife(100);
		}
	}

	private class BloodBar {
		public void draw(Graphics g) {
			Color c = g.getColor();
			g.setColor(Color.BLACK);
			g.drawRect(x, y - 10, Tank.WIDTH, 10);
			g.setColor(Color.RED);
			int w = WIDTH * life / 100;
			g.fillRect(x, y - 10, w, 10);
			g.setColor(c);
		}
	}
}
